package com.example.consult.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@ServerEndpoint("/websocket/consult/{userId}")
@Slf4j
public class WebSocketServer {

    private static AtomicInteger onlineNum = new AtomicInteger();

    //保存用户-用户session
    private static Map<String, Session> map = new ConcurrentHashMap<>();


    /**
     * 建立连接
     *
     * @param session session
     * @param userId  用户ID
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        int num = onlineNum.incrementAndGet();

        map.put(userId, session);
        log.info("新建立客户端连接，userId为：{}，当前连接数为：{}", userId ,num);
    }

    /**
     * 关闭连接
     *
     * @param session session
     */
    @OnClose
    public void onClose(Session session) {
        map.values().remove(session);
        int num = onlineNum.decrementAndGet();
        log.info("sessionId为{}的客户端连接关闭，当前剩余连接数为：{}", session.getId(), num);
    }

    /**
     * 客户端发送消息
     *
     * @param session session
     * @param message 消息
     */
    @OnMessage
    public void onMessage(Session session, String message) {
        log.info("sessionId : {} , onMessage : {}", session.getId(), message);
    }

    /**
     * 发生错误
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket发生错误：{}，Session ID： {}", error, session.getId());
    }

    /**
     * 向某个用户发送消息
     *
     * @param userId 用户id
     * @param message 消息
     */
    public static void sendMessage(String userId, String message) {
        if(!map.containsKey(userId)) {
            return;
        }else{
            Session session = map.get(userId);
            // getAsyncRemote()和getBasicRemote()异步与同步
            RemoteEndpoint.Async async = session.getAsyncRemote();
            //发送消息
            async.sendText(message);
        }
    }
    /**
     * 向所有在线人发送消息
     * @param message
     */
    public static void sendMessageForAll(String message) {
        //jdk8 新方法
        map.forEach((userId, session) -> sendMessage(userId, message));
    }

}